from json.decoder import JSONDecodeError
from flask import Flask, request
from flask import url_for, render_template
from functools import wraps
import config
import json
from database import tables

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False  # 防止中文显示错误


class ErrorCode:
    NO_ERROR = 0  # 成功
    JSON_ERROR = 1  # 传入的json格式有误
    KEY_ERROR = 2  # 参数中未包含指定的键
    UNKNOW_ERROR = -1


def return_data(data=[], code=ErrorCode.NO_ERROR, msg='faild'):
    return {
        'msg': [msg, 'success'][code == 0],
        'code': code,
        'data': data
    }


def catch_error(func):
    @wraps(func)
    def wapper(*arg, **karg):
        try:
            return return_data(func(*arg, **karg))
        except JSONDecodeError as e:
            return return_data(code=ErrorCode.JSON_ERROR, msg=str(e))
        except KeyError as e:
            return return_data(code=ErrorCode.KEY_ERROR, msg=str(e))
        except Exception:
            return return_data(code=ErrorCode.UNKNOW_ERROR)
    return wapper


@app.route("/info/RegionalData", methods=["GET"])  # 获取地区数据
@catch_error
def RegionalData():
    select_res = config.DB.select_table(tables.province, '*')
    ret_data = [{"area": it[0], "province": it[1],
                 "province_id": it[2]} for it in select_res]
    return ret_data


@app.route("/info/GetCarType", methods=["GET"])  # 获取汽车类型数据
@catch_error
def GetCarType():
    select_res = config.DB.select_table(['CarSellWithType'],
                                        ["car_type"], groupby=["car_type"])
    ret_data = [it[0] for it in select_res]
    return ret_data


@app.route("/overview/BaseCarSales", methods=["POST"])
@catch_error
def BaseCarSales():
    data = json.loads(request.form['data'])
    carType = data['CarType']
    Start_time = data['timeRange']['timeStart']
    End_time = data['timeRange']['timeEnd']
    group_list = ["car_type"]

    where = 'sell_time >= "%s" and sell_time <= "%s"' % (
        Start_time, End_time)

    select_res = config.DB.select_table(
        ['CarSellWithType'],
        ['car_type', 'sum(car_number)'],
        where,
        groupby=group_list
    )

    summary = [{"CarType": it[0], "SellNum": it[1]}
               for it in select_res if not carType or it[0] in carType]

    select_res = config.DB.select_table(
        ['CarSellWithType'],
        [
            'car_type',
            'sum(car_number)',
            'sell_time'],
        where,
        groupby=group_list + ['sell_time']
    )

    timeList = []
    for it in select_res:
        if it[2] not in timeList:
            timeList.append(it[2])
    timeList.sort()

    detail = {}
    for it in select_res:
        if not carType or it[0] in carType:
            detail.setdefault(it[0], [0] * len(timeList))
            detail[it[0]][timeList.index(it[2])] = it[1]
    timeList = [it[:-3] for it in timeList]
    return {'summary': summary, 'detail': detail, 'time': timeList}


@app.route("/overview/MonthlySales", methods=["POST"])
@catch_error
def MonthlySales():
    data = json.loads(request.form['data'])
    Start_time = data['timeRange']['timeStart']
    End_time = data['timeRange']['timeEnd']
    region_list = data['region']

    if region_list:
        regionWhere = " and (" + " or ".join(
            ['province_name = "%s"' % it for it in region_list]) + ")"
    else:
        regionWhere = ""

    where = 'time >= "%s" and time <= "%s"%s' % (
        Start_time, End_time, regionWhere)

    select_res = config.DB.select_table(
        tables.SellAllWithProvince,
        [
            tables.SellAllWithProvince.number.SUM,
            tables.SellAllWithProvince.time
        ],
        where,
        [tables.SellAllWithProvince.time]
    )

    detail = {
        "sellNum": [],
        "time": []
    }
    for it in select_res:
        detail['sellNum'].append(it[0])
        detail['time'].append(it[1][:-3])

    select_res = config.DB.select_table(
        tables.SellAllWithProvince,
        [
            tables.SellAllWithProvince.number.SUM,
            tables.SellAllWithProvince.province_name
        ],
        where,
        [tables.SellAllWithProvince.province_name]
    )

    summary = {
        'sellNum': [],
        'area': []
    }
    for it in select_res:
        summary['sellNum'].append(it[0])
        summary['area'].append(it[1])
    return {'summary': summary, 'detail': detail}


@app.route("/overview/CarSeries", methods=["POST"])
@catch_error
def CarSeries():
    data = json.loads(request.form['data'])
    Start_time = data['timeRange']['timeStart']
    End_time = data['timeRange']['timeEnd']
    carSeriesList = data['carSeries']
    if not carSeriesList:
        return []

    if carSeriesList:
        carSeriesWhere = " and (" + " or ".join(
            ['car_name = "%s"' % it for it in carSeriesList]) + ")"
    else:
        carSeriesWhere = ''

    where = 'sell_time >= "%s" and sell_time <= "%s"%s' % (
        Start_time, End_time, carSeriesWhere)

    select_res = config.DB.select_table(
        ['CarSellWithType'],
        ['car_name', 'car_number', 'sell_time'],
        where
    )

    ret_data = {}
    for it in select_res:
        ret_data.setdefault(it[0], {'time': [], 'sellNum': []})
        ret_data[it[0]]['sellNum'].append(it[1])
        ret_data[it[0]]['time'].append(it[2][:-3])
    return ret_data


@app.route("/overview/PriceRange", methods=["POST"])
@catch_error
def PriceRange():
    data = json.loads(request.form['data'])
    Start_time = data['timeRange']['timeStart']
    End_time = data['timeRange']['timeEnd']
    region_list = data['region']


config.AT.run()
app.run(host='127.0.0.1', port=5001)
config.AT.close()
